home *** CD-ROM | disk | FTP | other *** search
/ BCI NET 2 / BCI NET 2.iso / archives / programming / misc / amigem.lha / amigem / exec / memory.c < prev    next >
Encoding:
C/C++ Source or Header  |  1995-01-29  |  9.0 KB  |  382 lines

  1. #include <exec/alerts.h>
  2. #include <exec/execbase.h>
  3. #include <exec/tasks.h>
  4. #include <exec/memory.h>
  5. #include <exec/semaphores.h>
  6. #include <exec/devices.h>
  7. #include <exec/io.h>
  8. #include <clib/_exec.h>
  9. #include <stdio.h>
  10.  
  11. #include <amigem/fd_lib.h>
  12. #define LIBBASE struct ExecBase *SysBase
  13.  
  14. /*
  15.  * Allocate part of a MemChunk
  16.  */
  17. void SplitMemChunk(struct MemChunk **mc,APTR mem,ULONG size)
  18. {
  19.   struct MemChunk *next;
  20.   next=(*mc)->mc_Next;
  21.   if((ULONG)mem+size<(ULONG)(*mc)+(*mc)->mc_Bytes)
  22.   {
  23.     (*mc)->mc_Next=(struct MemChunk *)((ULONG)mem+size);
  24.     (*mc)->mc_Next->mc_Next=next;
  25.     (*mc)->mc_Next->mc_Bytes=((ULONG)(*mc)+(*mc)->mc_Bytes)-((ULONG)mem+size);
  26.     next=(*mc)->mc_Next;
  27.   }
  28.   if((ULONG)(*mc)<(ULONG)mem)
  29.   {
  30.     (*mc)->mc_Bytes=(ULONG)mem-(ULONG)(*mc);
  31.     next=*mc;
  32.   }
  33.   *mc=next;
  34. }
  35.  
  36. FD2(31,void *,Allocate,struct MemHeader *mh,A0,ULONG size,D0)
  37. {
  38.   struct MemChunk *p1,*p2;
  39.   size=(size+sizeof(struct MemChunk)-1)&~(sizeof(struct MemChunk)-1);
  40.   if(mh->mh_Free<size)
  41.     return NULL;
  42.   p1=(struct MemChunk *)&mh->mh_First;
  43.   p2=p1->mc_Next;
  44.   if(p2!=NULL)
  45.     for(;;)
  46.     {
  47.       if(p2->mc_Bytes>=size)
  48.       {
  49.         SplitMemChunk((struct MemChunk **)p1,p2,size);
  50.         break;
  51.       }
  52.       p1=p2;
  53.       p2=p1->mc_Next;
  54.       if(p2==NULL)
  55.         break;
  56.       if((ULONG)p2<(ULONG)p1+p1->mc_Bytes)
  57.         Alert(AN_MemCorrupt);
  58.     }
  59.   return p2;
  60. }
  61.  
  62. FD3(32,void,Deallocate,struct MemHeader *mh,A0,APTR mem,A1,ULONG size,D0)
  63. {
  64.   struct MemChunk *p1,*p2;
  65.   if(!(size=(size+sizeof(struct MemChunk)-1)&~(sizeof(struct MemChunk)-1)))
  66.     return;
  67.   p2  =(APTR)((ULONG)mem&~(sizeof(struct MemChunk)-1));
  68.   p2->mc_Bytes=size;
  69.   mh->mh_Free+=size;
  70.   if((p1=mh->mh_First)==NULL)
  71.   {
  72.     p2->mc_Next=NULL;
  73.     mh->mh_First=p2;
  74.   }
  75.   else
  76.     for(;;)
  77.     {
  78.       if(p1->mc_Next==NULL||(ULONG)p1->mc_Next>(ULONG)p2)
  79.       {
  80.         p2->mc_Next=p1->mc_Next;
  81.         p1->mc_Next=p2;
  82.         if((ULONG)p1+p1->mc_Bytes==(ULONG)p2)
  83.         {
  84.           p1->mc_Bytes+=size;
  85.           p2=p1;
  86.         }else if((ULONG)p1+p1->mc_Bytes>(ULONG)p2)
  87.           Alert(AN_FreeTwice);
  88.         p1=p2->mc_Next;
  89.         if(p1)
  90.           if((ULONG)p2+p2->mc_Bytes==(ULONG)p1)
  91.           {
  92.             p1->mc_Bytes+=p1->mc_Bytes;
  93.             p1->mc_Next=p1->mc_Next;
  94.           }
  95.           else if((ULONG)p2+p2->mc_Bytes>(ULONG)p1)
  96.             Alert(AN_FreeTwice);
  97.         break;
  98.       }
  99.       p1=p1->mc_Next;
  100.     }
  101. }
  102.  
  103. FD2(33,void *,AllocMem,ULONG size,D0,ULONG attrib,D1)
  104.   struct MemHeader *mh;
  105.   struct MemChunk *ret=NULL;
  106.   size=(size+sizeof(struct MemChunk)-1)&~(sizeof(struct MemChunk)-1);
  107.   Forbid();
  108.     mh=(struct MemHeader *)SysBase->MemList.lh_Head;
  109.     while(mh->mh_Node.ln_Succ!=NULL)
  110.     {
  111.       if(mh->mh_Free>=size&&!(attrib&~(MEMF_CLEAR|MEMF_REVERSE|mh->mh_Attributes)))
  112.       {
  113.         if(!(attrib&MEMF_REVERSE))
  114.           ret=Allocate(mh,size);
  115.         else
  116.         {
  117.           struct MemChunk *p1,*p2;
  118.           p1=(struct MemChunk *)&mh->mh_First;
  119.           p2=p1->mc_Next;
  120.           if(p2!=NULL)
  121.             for(;;)
  122.             {
  123.               if(p2->mc_Bytes>=size)
  124.                 ret=p1;
  125.               p1=p2;
  126.               p2=p1->mc_Next;
  127.               if(p2==NULL)
  128.                 break;
  129.               if((ULONG)p2<(ULONG)p1+p1->mc_Bytes)
  130.                 Alert(AN_MemCorrupt);
  131.             }
  132.           if(ret!=NULL)
  133.           {
  134.             p1=ret;
  135.             p2=p1->mc_Next;
  136.             ret=(struct MemChunk *)((char *)p2+p2->mc_Bytes-size);
  137.             SplitMemChunk((struct MemChunk **)p1,ret,size);
  138.             mh->mh_Free-=size;
  139.           }
  140.         }
  141.         if(ret!=NULL)
  142.         {
  143.           if(attrib&MEMF_CLEAR)
  144.           {
  145.             ULONG cnt,*p;
  146.             p=(ULONG *)ret;
  147.             cnt=size/sizeof(ULONG);
  148.             while(cnt--)
  149.               *p++=0;
  150.           }
  151.           break;
  152.         }
  153.       }
  154.       mh=(struct MemHeader *)mh->mh_Node.ln_Succ;
  155.     }
  156.   Permit();
  157.   return ret;
  158. }
  159.  
  160. FD2(35,void,FreeMem,void *mem,A1,ULONG size,D0)
  161. {
  162.   struct MemHeader *mh;
  163.   Forbid();
  164.     mh=(struct MemHeader *)SysBase->MemList.lh_Head;
  165.     while(mh->mh_Node.ln_Succ!=NULL)
  166.     {
  167.       if((ULONG)mem>=(ULONG)mh->mh_Lower&&(ULONG)mem<(ULONG)mh->mh_Upper)
  168.         Deallocate(mh,mem,size);
  169.     }
  170.   Permit();
  171. }
  172.  
  173. FD2(34,void *,AllocAbs,ULONG size,D0,void *mem,A1)
  174. {
  175.   struct MemChunk *ret=NULL;
  176.   struct MemHeader *mh;
  177.   size=(size+((ULONG)mem&(sizeof(struct MemChunk)-1))+
  178.         sizeof(struct MemChunk)-1)&~(sizeof(struct MemChunk)-1);
  179.   mem=(void *)((ULONG)mem&~(sizeof(struct MemChunk)-1));
  180.   Forbid();
  181.     mh=(struct MemHeader *)SysBase->MemList.lh_Head;
  182.     while(mh->mh_Node.ln_Succ!=NULL)
  183.     {
  184.       if((ULONG)mem>=(ULONG)mh->mh_Lower&&(ULONG)mem<=(ULONG)mh->mh_Upper)
  185.       {
  186.         struct MemChunk *p1,*p2;
  187.         p1=(struct MemChunk *)&mh->mh_First;
  188.         p2=p1->mc_Next;
  189.         if(p2!=NULL)
  190.         {
  191.           for(;;)
  192.           {
  193.             if((ULONG)p2+p2->mc_Bytes>=(ULONG)mem+size&&(ULONG)p2<=(ULONG)mem)
  194.             {
  195.               ret=p1;
  196.               break;
  197.             }
  198.             p1=p2;
  199.             p2=p1->mc_Next;
  200.             if(p2==NULL)
  201.               break;
  202.             if((ULONG)p2<(ULONG)p1+p1->mc_Bytes)
  203.               Alert(AN_MemCorrupt);
  204.           }
  205.           if(ret!=NULL)
  206.           {
  207.             ret=(struct MemChunk *)mem;
  208.             SplitMemChunk((struct MemChunk **)p1,ret,size);
  209.             mh->mh_Free-=size;
  210.             break;
  211.       }
  212.         }
  213.       }
  214.       mh=(struct MemHeader *)mh->mh_Node.ln_Succ;
  215.     }
  216.   Permit();
  217.   return ret;
  218. }
  219.  
  220. FD2(114,void *,AllocVec,ULONG size,D0,ULONG attrib,D1)
  221. {
  222.   ULONG *ret;
  223.   size+=sizeof(ULONG);
  224.   if((ret=(ULONG *)AllocMem(size,attrib))!=NULL)
  225.     *ret=size;
  226.   return ret+1;
  227. }
  228.  
  229. FD1(115,void,FreeVec,void *mem,A1)
  230. {
  231.   ULONG *p=(ULONG *)mem;
  232.   if(p!=NULL)
  233.   {
  234.     p--;
  235.     FreeMem(p,*p);
  236.   }
  237. }
  238.  
  239. FD1(37,struct MemList *,AllocEntry,struct MemList *ml,A0)
  240. {
  241.   struct MemList *ret;
  242.   ULONG i;
  243.   if((ret=(struct MemList *)AllocMem(sizeof(struct MemList)-sizeof(struct MemEntry)+
  244.           sizeof(struct MemEntry)*ml->ml_NumEntries,MEMF_PUBLIC))==NULL)
  245.     return (struct MemList *)(MEMF_PUBLIC|0x80ul<<(sizeof(APTR)-1)*8);
  246.   ret->ml_NumEntries=ml->ml_NumEntries;
  247.   for(i=0;i<ml->ml_NumEntries;i++)
  248.   {
  249.     if((ret->ml_ME[i].me_Addr=AllocMem(ml->ml_ME[i].me_Length,ml->ml_ME[i].me_Reqs))==NULL)
  250.     {
  251.       ml=(struct MemList *)((ULONG)ml->ml_ME[i].me_Reqs|0x80ul<<(sizeof(APTR)-1)*8);
  252.       for(;i-->0;)
  253.         FreeMem(ret->ml_ME[i].me_Addr,ret->ml_ME[i].me_Length);
  254.       FreeMem(ret,sizeof(struct MemList)-sizeof(struct MemEntry)+
  255.                   sizeof(struct MemEntry)*ret->ml_NumEntries);
  256.       return ml;
  257.     }
  258.     ret->ml_ME[i].me_Length=ml->ml_ME[i].me_Length;
  259.   }
  260.   return ret;
  261. }
  262.  
  263. FD1(38,void,FreeEntry,struct MemList *ml,A0)
  264. {
  265.   ULONG i;
  266.   for(i=0;i<ml->ml_NumEntries;i++)
  267.     FreeMem(ml->ml_ME[i].me_Addr,ml->ml_ME[i].me_Length);
  268.   FreeMem(ml,sizeof(struct MemList)-sizeof(struct MemEntry)+
  269.              sizeof(struct MemEntry)*ml->ml_NumEntries);
  270. }
  271.  
  272. FD5(103,void,AddMemList,ULONG size,D0,ULONG attributes,D1,LONG pri,D2,APTR base,A0,STRPTR name,A1)
  273. {
  274.   struct MemHeader *mh;
  275.   /* Should have to look here if it matches some other memheader */
  276.   mh=(struct MemHeader *)base;
  277.   mh->mh_Node.ln_Pri=pri;
  278.   mh->mh_Node.ln_Name=name;
  279.   mh->mh_Attributes=attributes;
  280.   mh->mh_First=(struct MemChunk *)(mh+1);
  281.   mh->mh_First->mc_Next=NULL;
  282.   mh->mh_First->mc_Bytes=size-sizeof(struct MemHeader);
  283.   mh->mh_Lower=base;
  284.   mh->mh_Upper=(APTR)((char *)base+size);
  285.   mh->mh_Free=size-sizeof(struct MemHeader);
  286.   Forbid();
  287.     Enqueue(&SysBase->MemList,&mh->mh_Node);
  288.   Permit();
  289. }
  290.  
  291. FD1(89,ULONG,TypeOfMem,void *mem,A1)
  292. {
  293.   ULONG ret=0;
  294.   struct MemHeader *mh;
  295.   Forbid();
  296.     mh=(struct MemHeader *)SysBase->MemList.lh_Head;
  297.     while(mh->mh_Node.ln_Succ!=NULL)
  298.     {
  299.       if((ULONG)mem>=(ULONG)mh->mh_Lower&&(ULONG)mem<=(ULONG)mh->mh_Upper)
  300.       {
  301.         ret=mh->mh_Attributes;
  302.         break;
  303.       }
  304.       mh=(struct MemHeader *)mh->mh_Node.ln_Succ;
  305.     }
  306.   Permit();
  307.   return ret;
  308. }
  309.  
  310. FD3(104,void,CopyMem,APTR source,A0,APTR dest,A1,unsigned long size,D0)
  311. {
  312.   UBYTE *s=(UBYTE *)source,*d=(UBYTE *)dest;
  313.   if(size&1)
  314.   {
  315.     *d++=*s++;
  316.     size--;
  317.   }
  318.   if(size&2)
  319.   {
  320.     *d++=*s++;
  321.     *d++=*s++;
  322.     size-=2;
  323.   }
  324.   size>>=2;
  325.   if(size)
  326.     do
  327.     {
  328.       *d++=*s++;
  329.       *d++=*s++;
  330.       *d++=*s++;
  331.       *d++=*s++;      
  332.     }
  333.     while(--size);    
  334. }
  335.  
  336. FD3(105,void,CopyMemQuick,ULONG *source,A0,ULONG *dest,A1,ULONG size,D0)
  337. {
  338.   if(size&4)
  339.   {
  340.     *dest++=*source++;
  341.     size-=4;
  342.   }
  343.   if(size&8)
  344.   {
  345.     *dest++=*source++;
  346.     *dest++=*source++;
  347.     size-=8;
  348.   }
  349.   size>>=4;
  350.   if(size)
  351.     do
  352.     {
  353.       *dest++=*source++;
  354.       *dest++=*source++;
  355.       *dest++=*source++;
  356.       *dest++=*source++;      
  357.     }
  358.     while(--size);
  359. }
  360.  
  361. FD1(36,ULONG,AvailMem,ULONG attributes,D1)
  362. { return 0; }
  363.  
  364. FD3(116,void *,CreatePool,ULONG memFlags,D0,ULONG puddleSize,D1,ULONG treshSize,D2)
  365. { return NULL; }
  366.  
  367. FD1(117,void,DeletePool,void *poolHeader,A0)
  368. {}
  369.  
  370. FD2(118,void *,AllocPooled,void *poolHeader,A0,ULONG memSize,D0)
  371. { return NULL; }
  372.  
  373. FD3(119,void,FreePooled,void *poolHeader,A0,void *memory,A1,ULONG memSize,D0)
  374. {}
  375.  
  376. FD1(129,void,AddMemHandler,struct Interrupt *memHandler,A1)
  377. {}
  378.  
  379. FD1(130,void,RemMemHandler,struct Interrupt *memHandler,A1)
  380. {}
  381.